const fs = require('fs')
const https = require('https')
const http = require('http')
const { pipeline } = require('stream')
const path = require('path')
const { HttpsProxyAgent } = require('https-proxy-agent')

// 代理IP池（建议使用付费住宅代理）
const PROXY_POOL = [
  'http://user:pass@proxy1.example.com:8080',
  'http://user:pass@proxy2.example.com:8080'
]

// 抖音专用请求头生成器
function getDouyinHeaders() {
  return {
    'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1',
    'Referer': 'https://www.douyin.com/',
    'Origin': 'https://www.douyin.com',
    'Accept': 'video/webm,video/ogg,video/*;q=0.9',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Sec-Fetch-Dest': 'video',
    'Sec-Fetch-Mode': 'no-cors',
    'Sec-Fetch-Site': 'cross-site',
    'x-tt-request-tag': 'true',
    'Connection': 'keep-alive'
  }
}

/**
 * 增强版抖音视频下载器
 * @param {string} videoUrl - 视频直链
 * @param {string} savePath - 本地保存路径
 * @param {object} [options] - 高级选项
 * @param {number} [options.retry=3] - 重试次数
 * @param {boolean} [options.useProxy=true] - 是否使用代理
 * @returns {Promise<string>} - 保存的文件路径
 */
async function downloadVideo(videoUrl, savePath, { retry = 3, useProxy = false } = {}) {
  // 确保目录存在
  await fs.promises.mkdir(path.dirname(savePath), { recursive: true })

  let lastError;
  const protocol = videoUrl.startsWith('https') ? https : http

  for (let attempt = 0; attempt < retry; attempt++) {
    try {
      const file = fs.createWriteStream(savePath)
      const headers = getDouyinHeaders()

      // 代理配置
      let agent;
      if (useProxy && PROXY_POOL.length > 0) {
        const proxy = PROXY_POOL[attempt % PROXY_POOL.length]
        agent = new HttpsProxyAgent(proxy)
        headers['X-Forwarded-For'] = generateRandomIP(); // 伪造IP
      }

      const response = await new Promise((resolve, reject) => {
        const req = protocol.get(videoUrl, { 
          headers,
          agent,
          timeout: 30000
        }, (res) => {
          if ([301, 302, 307, 308].includes(res.statusCode)) {
            // 处理重定向
            if (!res.headers.location) {
              return reject(new Error('抖音视频重定向失败'))
            }
            return downloadVideo(
              new URL(res.headers.location, videoUrl).toString(),
              savePath,
              { retry: retry - attempt, useProxy }
            ).then(resolve).catch(reject);
          }

          if (res.statusCode !== 200) {
            return reject(new Error(`抖音服务器拒绝，状态码: ${res.statusCode}`))
          }
          resolve(res)
        })

        req.on('error', reject)
        req.on('timeout', () => req.destroy(new Error('请求超时')))
      });

      // 显示下载进度
      const contentLength = parseInt(response.headers['content-length'], 10)
      let downloaded = 0
      response.on('data', (chunk) => {
        downloaded += chunk.length
        if (contentLength) {
          process.stdout.write(`抖音视频下载进度: ${Math.round((downloaded / contentLength) * 100)}%\r`)
        }
      })

      await new Promise((resolve, reject) => {
        pipeline(response, file, (err) => {
          if (err) {
            fs.unlink(savePath, () => {})
            reject(err)
          } else {
            process.stdout.write('\n')
            resolve()
          }
        })
      })

      return savePath
    } catch (err) {
      lastError = err
      if (fs.existsSync(savePath)) fs.unlinkSync(savePath)
      if (attempt < retry - 1) {
        await new Promise(r => setTimeout(r, 1000 * (attempt + 1)))
      }
    }
  }

  throw lastError || new Error('抖音视频下载失败')
}

// 生成随机中国大陆IP
function generateRandomIP() {
  const segments = [
    Math.floor(Math.random() * 255) + 1,
    Math.floor(Math.random() * 255),
    Math.floor(Math.random() * 255),
    Math.floor(Math.random() * 255)
  ]
  return segments.join('.')
}

module.exports = { 
  downloadVideo,
  getDouyinHeaders // 暴露用于其他模块
}